package com.app.util;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JSONSerializer;
import net.sf.json.JsonConfig;

import org.apache.commons.beanutils.DynaBean;


@SuppressWarnings("unchecked")
public class JSONUtil {
	 private String string;    
	   private int integer;    
	   private double dooble;    
	   private boolean bool;  
	   //类型type
	   public static final String OBJECT = "object";
	   
	   public static final String MAP = "map";
	 
	   
	public static List<JSONObject> getJSONArrayFromMapList(List<Map> modeList){
		List<JSONObject> list = new ArrayList<JSONObject>();
		for(Map map:modeList){
			Set set = map.keySet();
			JSONObject json = new JSONObject();
			Iterator it  = set.iterator();
			while(it.hasNext()){
				String key = (String)it.next();
				if(key!=null){
					json.put(key, Util.getEmptyMapValue(map,key));
				}
			}
			list.add(json);
		}
		return list;
	}
	
	/**
	 * 将list<Map> 转换为jsonObject，主要用于分页
	 * @param num 数据集合的总个数
	 * @param from 数据集合
	 * @param type 类型：分为将对象转换为JSONObject、将Map转换为JSONObject
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static String listToJSONStringWithTotal(Integer num, List dataList, String type) {
		List<JSONObject> jsonList = new ArrayList<JSONObject>();
		if(MAP.equals(type)){
			jsonList = mapListToJSONObjectList(dataList);
		}else{
			jsonList = objectListToJSONObjectList("", dataList);
		}
		HashMap<String, Object> ma = new HashMap<String, Object>();
		ma.put("total", num);
		ma.put("results", jsonList);
		return JSONSerializer.toJSON(ma).toString();
	}
	
	/**
	 * 将List<Map> 转换为jsonObject，用于不用分页的gridPanel或其他用途
	 * @param from 数据集合
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static String listMaptoJSONStringWithTotal(List<Map> from) {
		List<JSONObject> jsonList = mapListToJSONObjectList(from);
		HashMap<String, Object> ma = new HashMap<String, Object>();
		ma.put("total", jsonList.size());
		ma.put("results", jsonList);
		return JSONSerializer.toJSON(ma).toString();
	}
	
	/**
	 * 将List<Map> 转换为jsonObject字符串，主要用于下拉框
	 * @param from
	 * @param resultName 
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static String listMapToJSONString(List<Map> from, String resultName) {
		
		if (from.size() != 0) {
			JSONArray list = mapListToJSONObjectList(from);
			Map<String, Object> ma = new HashMap<String, Object>();
			ma.put(resultName, list);
			String str = JSONSerializer.toJSON(ma).toString();
			return str;
		} else
			return "";

	}

	/**
	 * 将list对象转换为JSONArray对象
	 * @param listMap
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static JSONArray mapListToJSONObjectList(List<Map> listMap) {
		JSONArray listJSON = new JSONArray();
		for (int i = 0; i < listMap.size(); i++) {
			JSONObject json = mapToJSONObject(listMap.get(i));
			listJSON.add(json);
		}
		
		return listJSON;
	}
	
	/**
	 * 将对象转化为JSONObject,并放到jsonArray里面
	 * @param objName 对象名称，例如：在页面中name的属性"res.resCode",则res是可以自定义的，此处objectName为res
	 * @param objectList 对象的集合
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public static JSONArray objectListToJSONObjectList(String objName, List objectList){
		JSONArray listJSON = new JSONArray();
		
		for(int i = 0; i < objectList.size(); i++){
			Object obj = objectList.get(i);
			Map map = new HashMap();
			//获得对象的类的对象
			Class clazz = obj.getClass();
			
			try {
				getFieldsAndToMapOfObject(objName, obj, clazz, map);
			} catch (Exception e) {
				e.printStackTrace();
			}
			JSONObject json = mapToJSONObject(map);
			listJSON.add(json);
		}
		
		return listJSON;
	}
	
	/**
	 * 把Map转换成JSONObject
	 * @param map
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static JSONObject mapToJSONObject(Map map) {
		Iterator keySet = map.keySet().iterator();
		JSONObject json = new JSONObject();
		while (keySet.hasNext()) {
			String key = keySet.next().toString();
			json.put(key,Util.getStringOfObject(map.get(key)));
		}
		return json;
	}
	
	/**
	 * 当对象被load的时候，将对象封装成JSONObject对象，并转换为字符串
	 * @param objName 对象的名称
	 * @param obj 对象
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static String ObjectToJSONObject(String objName, Object obj){
		Map map = new HashMap();
		try {
			
			//获得对象的类的对象
			Class clazz = obj.getClass();
			
			getFieldsAndToMapOfObject(objName, obj, clazz, map);
			
//			//获得对象的所有属性
//			Field[] fs = clazz.getDeclaredFields();
//			for(Field f: fs){
//				//获得属性名称
//				String fName = f.getName();
//				//方法的名字
//				String methodName = "get" + fName.substring(0,1).toUpperCase() + fName.substring(1);
//			
//				//查找方法
//				Method method = clazz.getMethod(methodName);
//				Object mObj = method.invoke(obj);
//				if(mObj != null){
//					map.put(objName + "." + fName, ObjectToStringUtil.getStringOfObject(mObj));
//				}
//			}
			
//			//遍历父类属性集合
//			if(clazz.getGenericSuperclass() != null){
//				Class superClazz = clazz.getSuperclass();
//				
//				//获得对象父类的所有属性
//				Field[] pFs = superClazz.getDeclaredFields();
//				for(Field f: pFs){
//				//获得属性名称
//				String fName = f.getName();
//				//方法的名字
//				String methodName = "get" + fName.substring(0,1).toUpperCase() + fName.substring(1);
//				
//					//查找方法
//					Method method = clazz.getMethod(methodName);
//					Object mObj = method.invoke(obj);
//					if(mObj != null){
//						map.put(objName + "." + fName, ObjectToStringUtil.getStringOfObject(mObj));
//					}
//				}
//			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		JSONObject json = mapToJSONObject(map);
		JSONObject json1 = new JSONObject();
		json1.put("success", true);
		json1.put("data", json);
		return json1.toString();
	}
	
	/**
	 * 迭代得到对象及其父对象的属性，将其放到map里面
	 * @param objectName 对象名称，例如：在页面中name的属性"res.resCode",则res是可以自定义的，此处objectName为res
	 * @param obj 对象
	 * @param clazz obj的Class
	 * @param map 存放数据的map，对象及其父对象的所有属性将放到map里面
	 * @return
	 * @throws Exception
	 */
	public static Class getFieldsAndToMapOfObject(String objectName, Object obj, 
			Class clazz, Map map) throws Exception{
		if(clazz == null){
			return null;
		}
		
		//获得对象的所有属性
		Field[] fs = clazz.getDeclaredFields();
		//判断是否传入objectName,如果传入则jsonObject展现方式为{'res.name': 'sy'}
		//如果没有传入，则结果为：{'name': 'sy'}
		if(!"".equals(objectName)){
			objectName = objectName + ".";
		}
		for(Field f: fs){
			//获得属性名称
			String fName = f.getName();
			//属性的类型
			Type type = f.getGenericType();
			//方法名称
			String methodName = "";
			String fNameUpperTheFirstCharacter = fName.substring(0,1).toUpperCase() + fName.substring(1);

			if("boolean".equals(type.toString())){
				methodName = "is" + fNameUpperTheFirstCharacter;
			}else{
				methodName = "get" + fNameUpperTheFirstCharacter;
			}
			//查找方法
			Method method = clazz.getMethod(methodName);
			Object mObj = method.invoke(obj);
			if(mObj != null){
				map.put(objectName + fName,Util.getStringOfObject(mObj));
			}
		}
		
		return getFieldsAndToMapOfObject(objectName, obj, clazz.getSuperclass(), map);
	}	
	public String getString() {
		return string;
	}


	public void setString(String string) {
		this.string = string;
	}


	public int getInteger() {
		return integer;
	}


	public void setInteger(int integer) {
		this.integer = integer;
	}


	public double getDooble() {
		return dooble;
	}


	public void setDooble(double dooble) {
		this.dooble = dooble;
	}


	public boolean isBool() {
		return bool;
	}


	public void setBool(boolean bool) {
		this.bool = bool;
	}


	@SuppressWarnings("unchecked")
	public static void main(String[] args) {
		System.out.println("**Creating a JSONObject from scratch**");
		JSONObject json = new JSONObject();    
		json.element("string", "JSON");    
        json.element("integer", "1");    
        json.element("double", "2.0");    
        json.element("boolean", "true");  
        System.out.println(json.toString()); 
		System.out.println(json.getString("string"));          
		System.out.println(json.getInt("integer"));          
		System.out.println(json.getDouble("double"));          
		System.out.println(json.getBoolean("boolean")); 

		
		System.out.println("**Creating a JSONObj from a JSON formatted string**");
		String str = "{string:'JSON', integer: 1, double: 2.0, boolean: true}";    
		JSONObject jsonObject = (JSONObject)JSONSerializer.toJSON(str);    
		System.out.println(jsonObject.toString()); 
		System.out.println(jsonObject.getString("string"));          
		System.out.println(jsonObject.getInt("integer"));          
		System.out.println(jsonObject.getDouble("double"));          
		System.out.println(jsonObject.getBoolean("boolean"));  
		

		System.out.println("**Creating a JSONObject from a Map**");
		Map map = new HashMap();    
		map.put("string", "JSON");    
		map.put("integer", "1");    
		map.put("double", "2.0");    
		map.put("boolean", "true");    
		JSONObject jsonObject2 = (JSONObject) JSONSerializer.toJSON(map);    
		System.out.println(jsonObject2.getString("string"));          
		System.out.println(jsonObject2.getInt("integer"));          
		System.out.println(jsonObject2.getDouble("double"));          
		System.out.println(jsonObject2.getBoolean("boolean"));  
		
		
		System.out.println("**Creating a JSONObject from javabean**");
		JSONUtil bean = new JSONUtil();    
		bean.setString("JSON");    
		bean.setInteger(1);    
		bean.setDooble(2.0d);    
		bean.setBool(true);    
		JSONObject jsonObject3 = (JSONObject) JSONSerializer.toJSON(bean);    
		System.out.println(jsonObject3.getString("string"));          
		System.out.println(jsonObject3.getInt("integer"));          
		System.out.println(jsonObject3.getDouble("dooble"));          
		System.out.println(jsonObject3.getBoolean("bool"));  
		
		JSONArray jsonArray = new JSONArray();    
		jsonArray.element("JSON");    
        jsonArray.element("1");    
        jsonArray.element("2.0");   
        jsonArray.element("true");    
        System.out.println(jsonArray.getString(0));          
        System.out.println(jsonArray.getInt(1));          
        System.out.println(jsonArray.getDouble(2));          
        System.out.println(jsonArray.getBoolean(3)); 
        
        String str2 = "['JSON', 1, 2.0, true]";    
        JSONArray jsonArray2 = (JSONArray)JSONSerializer.toJSON(str2);    
        System.out.println(jsonArray2.getString(0));          
        System.out.println(jsonArray2.getInt(1));          
        System.out.println(jsonArray2.getDouble(2));          
        System.out.println(jsonArray2.getBoolean(3)); 
        
        List list = new ArrayList();    
        list.add("JSON");    
        list.add("1");    
        list.add("2.0");    
        list.add("true");    
        JSONArray jsonArray3 = (JSONArray) JSONSerializer.toJSON(list);    
        System.out.println(jsonArray3.getString(0));          
        System.out.println(jsonArray3.getInt(1));          
        System.out.println(jsonArray3.getDouble(2));          
        System.out.println(jsonArray3.getBoolean(3)); 
        
        
        Object[] array = new Object[]{"JSON", "1", "2.0", "true"};    
        JSONArray jsonArray4 = (JSONArray) JSONSerializer.toJSON(array);    
        System.out.println(jsonArray4.getString(0));          
        System.out.println(jsonArray4.getInt(1));          
        System.out.println(jsonArray4.getDouble(2));          
        System.out.println(jsonArray4.getBoolean(3));  
        
        String str4 = "{'string':'JSON', 'integer': 1, 'double': 2.0, 'boolean': true}";    
        JsonConfig jsonConfig = new JsonConfig();    
        jsonConfig.setExcludes(new String[]{"double", "boolean"});    
        JSONObject jsonObject5 = (JSONObject) JSONSerializer.toJSON(str4, jsonConfig);    
        System.out.println(jsonObject5.getString("string"));          
        System.out.println(jsonObject5.getInt("integer"));          
        System.out.println(jsonObject5.has("double"));       
        System.out.println(jsonObject5.has("boolean"));   
        
        String str5 = "{'string':'JSON', 'integer': 1, 'double': 2.0, 'boolean': true}";    
        JSONObject jsonObject6 = (JSONObject) JSONSerializer.toJSON(str5);    
        DynaBean bean2 = (DynaBean) JSONSerializer.toJava(jsonObject6);    
        System.out.println(bean2.get("string"));          
        System.out.println(bean2.get("integer"));          
        System.out.println(bean2.get("double"));          
        System.out.println(bean2.get("boolean"));  
        
        /********
         * JSONObject to DynaBean
		String str = "{'string':'JSON', 'integer': 1, 'double': 2.0, 'boolean': true}";    
		JSONObject jsonObject = (JSONObject) JSONSerializer.toJSON( str );    
		DynaBean bean = (DynaBean) JSONSerializer.toJava( jsonObject );    
		assertEquals( "JSON", bean.get("string") );          
		assertEquals( new Integer(1), bean.get("integer") );          
		assertEquals( new Double(2.0), bean.get("double") );          
		assertEquals( Boolean.TRUE, bean.get("boolean") );       
		String str = "{'string':'JSON', 'integer': 1, 'double': 2.0, 'boolean': true}";
		JSONObject jsonObject = (JSONObject) JSONSerializer.toJSON( str );
		DynaBean bean = (DynaBean) JSONSerializer.toJava( jsonObject );
		assertEquals( "JSON", bean.get("string") );      
		assertEquals( new Integer(1), bean.get("integer") );      
		assertEquals( new Double(2.0), bean.get("double") );      
		assertEquals( Boolean.TRUE, bean.get("boolean") );   
		[Index|From JSON to Java] 
		JSONObject to JavaBean
		public class MyJavaBean {    
		   private String string;    
		   private int integer;    
		   private double dooble;    
		   private boolean bool;    
		   
		   // getters & setters    
		}    
		   
		MyJavaBean bean = new MyJavaBean();    
		bean.setString( "JSON" );    
		bean.setInteger( 1 );    
		bean.setDooble( 2.0d );    
		bean.setBool( true );    
		JSONObject jsonObject = (JSONObject) JSONSerializer.toJSON( bean );    
		JsonConfig jsonConfig = new JsonConfig();    
		jsonConfig.setRootClass( MyJavaBean.class );    
		MyJavaBean bean2 = (MyJavaBean) JSONSerializer.toJava( jsonObject, jsonConfig );    
		assertNotNull( bean2 );    
		assertEquals( "JSON", bean2.getString() );    
		assertEquals( 1, bean2.getInteger() );    
		assertEquals( 2.0d, bean2.getDooble(), 0d );    
		assertTrue( bean2.getBool() );    
		public class MyJavaBean {
		   private String string;
		   private int integer;
		   private double dooble;
		   private boolean bool;
		
		   // getters & setters
		}
		
		MyJavaBean bean = new MyJavaBean();
		bean.setString( "JSON" );
		bean.setInteger( 1 );
		bean.setDooble( 2.0d );
		bean.setBool( true );
		JSONObject jsonObject = (JSONObject) JSONSerializer.toJSON( bean );
		JsonConfig jsonConfig = new JsonConfig();
		jsonConfig.setRootClass( MyJavaBean.class );
		MyJavaBean bean2 = (MyJavaBean) JSONSerializer.toJava( jsonObject, jsonConfig );
		assertNotNull( bean2 );
		assertEquals( "JSON", bean2.getString() );
		assertEquals( 1, bean2.getInteger() );
		assertEquals( 2.0d, bean2.getDooble(), 0d );
		assertTrue( bean2.getBool() );
		[Index|From JSON to Java] 
		JSONArray to List
		List input = new ArrayList();    
		input.add( "JSON" );    
		input.add( "1" );    
		input.add( "2.0" );    
		input.add( "true" );    
		JSONArray jsonArray = (JSONArray) JSONSerializer.toJSON( input );    
		List output = (List) JSONSerializer.toJava( jsonArray );    
		ArrayAssertions.assertEquals( input, output );    
		List input = new ArrayList();
		input.add( "JSON" );
		input.add( "1" );
		input.add( "2.0" );
		input.add( "true" );
		JSONArray jsonArray = (JSONArray) JSONSerializer.toJSON( input );
		List output = (List) JSONSerializer.toJava( jsonArray );
		ArrayAssertions.assertEquals( input, output );
		[Index|From JSON to Java] 
		JSONArray to array
		List input = new ArrayList();    
		input.add( "JSON" );    
		input.add( "1" );    
		input.add( "2.0" );    
		input.add( "true" );    
		JSONArray jsonArray = (JSONArray) JSONSerializer.toJSON( input );    
		JsonConfig jsonConfig = new JsonConfig();    
		jsonConfig.setArrayMode( JsonConfig.MODE_OBJECT_ARRAY );    
		Object[] output = (Object[]) JSONSerializer.toJava( jsonArray, jsonConfig );    
		Object[] expected = new Object[]{ "JSON", "1", "2.0", "true" };    
		ArrayAssertions.assertEquals( expected, output);    
		List input = new ArrayList();
		input.add( "JSON" );
		input.add( "1" );
		input.add( "2.0" );
		input.add( "true" );
		JSONArray jsonArray = (JSONArray) JSONSerializer.toJSON( input );
		JsonConfig jsonConfig = new JsonConfig();
		jsonConfig.setArrayMode( JsonConfig.MODE_OBJECT_ARRAY );
		Object[] output = (Object[]) JSONSerializer.toJava( jsonArray, jsonConfig );
		Object[] expected = new Object[]{ "JSON", "1", "2.0", "true" };
		ArrayAssertions.assertEquals( expected, output);
		[Index|From JSON to Java] 
		JSONArray to array (type conversion)
		List input = new ArrayList();    
		input.add( "1" );    
		input.add( "2" );    
		input.add( "3.0" );    
		JSONArray jsonArray = (JSONArray) JSONSerializer.toJSON( input );    
		JsonConfig jsonConfig = new JsonConfig();    
		jsonConfig.setArrayMode( JsonConfig.MODE_OBJECT_ARRAY );    
		jsonConfig.setRootClass( Integer.TYPE );    
		int[] output = (int[]) JSONSerializer.toJava( jsonArray, jsonConfig );    
		int[] expected = new int[]{ 1, 2, 3 };    
		ArrayAssertions.assertEquals( expected, output);    
		List input = new ArrayList();
		input.add( "1" );
		input.add( "2" );
		input.add( "3.0" );
		JSONArray jsonArray = (JSONArray) JSONSerializer.toJSON( input );
		JsonConfig jsonConfig = new JsonConfig();
		jsonConfig.setArrayMode( JsonConfig.MODE_OBJECT_ARRAY );
		jsonConfig.setRootClass( Integer.TYPE );
		int[] output = (int[]) JSONSerializer.toJava( jsonArray, jsonConfig );
		int[] expected = new int[]{ 1, 2, 3 };
		ArrayAssertions.assertEquals( expected, output);
		[Index|From JSON to Java] 
		JSONObject to JavaBean, exclude properties with filters
		public class MyJavaBean {    
		   private String string;    
		   private int integer;    
		   private double dooble = 0d;    
		   private boolean bool;    
		   
		   // getters & setters    
		}    
		   
		MyJavaBean bean = new MyJavaBean();    
		bean.setString( "JSON" );    
		bean.setInteger( 1 );    
		bean.setDooble( 2.0d );    
		bean.setBool( true );    
		JSONObject jsonObject = (JSONObject) JSONSerializer.toJSON( bean );    
		JsonConfig jsonConfig = new JsonConfig();    
		jsonConfig.setRootClass( MyJavaBean.class );    
		jsonConfig.setJavaPropertyFilter( new PropertyFilter(){      
		   public boolean apply( Object source, String name, Object value ) {      
		      if( "bool".equals( name ) || "dooble".equals( name ) ){      
		         return true;      
		      }      
		      return false;      
		   }      
		});     
		MyJavaBean bean2 = (MyJavaBean) JSONSerializer.toJava( jsonObject, jsonConfig );    
		assertNotNull( bean2 );    
		assertEquals( "JSON", bean2.getString() );    
		assertEquals( 1, bean2.getInteger() );    
		assertEquals( 0d, bean2.getDooble(), 0d );    
		assertFalse( bean2.getBool() );  
         */
	}
	public static String getCount(String sql){
		return sql.toLowerCase().split("limit")[0];
	}
	public static String getPage(List list, int total) {
		List li = JSONUtil.getJSONArrayFromMapList(list);
		Map m = new HashMap();
		m.put("totalCount", total);
		m.put("rows", li);
		return JSONSerializer.toJSON(m).toString();
	}
}
